<?php
/**
 * <https://y.st./>
 * Copyright © 2016-2019 Alex Yst <mailto:copyright@y.st>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org./licenses/>.
**/

/**
 * Closures are for writing functions that aren't fit to be reused in
 * other projects. If a function isn't fit to be used in other
 * projects, it clearly hasn't been generalized enough. As such, the
 * code in this file really should be generalized more. I'll rewrite
 * this code as I figure out how to better generalize it.
 * 
 * I'm stashing closures in a pseudo-namespace by prefixing their names
 * with "$¢_". It's ugly, clearly, but then again, so are the closures
 * here themselves.
**/
$¢_build_term_update_schedule = function($year, $month, $day) {
	$update = new \st\y\datetime($year, $month, $day);
	$update->add(new DateInterval('P6D'));
	
	$week = new DateInterval('P7D');
	
	$return = '';
	
	for($i=0;$i<7;$i++):
		$return .= <<<END
	<li>
		<time>{$update->format('l, Y-m-d')}</time>
	</li>

END;
		$update->add($week);
	endfor;
	
	$update->add(new DateInterval('P1D'));
		$return .= <<<END
	<li>
		<time>{$update->format('l, Y-m-d')}</time>
	</li>
END;
return $return; };

$¢_set_data_from_path = function(string $filename, array $xhtml): array {
	global $a;
	global $coursework_nav;
	global $latest_entry;
	global $interval;
	global $entry;

	if(substr('/'.$filename, -12) == '/index.xhtml'):
		$xhtml['<{URI path minus slash}>'] = substr($filename, 0, -11);
	else:
		$xhtml['<{URI path minus slash}>'] = $filename;
	endif;

	$xhtml['<{stripped title}>'] = strip_tags($xhtml['<{title}>']);
	$xhtml['<{encoded path minus slash}>'] = urlencode($xhtml['<{URI path minus slash}>']);

	$xhtml['<{nav}>'] = "<nav>\n";

	if(substr($filename, 0, 3) == 'en/'):
		$xhtml['<{nav}>'] .= <<<END
	<p>
		<a href="/en/coursework/">Coursework</a> |
		<a href="/en/take-down/">Take-down requests</a> |
		<a href="/en/">Home</a> |
		<a href="/en/a/about.xhtml">About</a> |
		<a href="/en/a/contact.xhtml">Contact</a> |
		<a href="/a/canary.txt">Canary</a> |
		<a href="/en/URI_research/">$a[URI] research</a> |
		<a href="/en/opinion/">Opinions</a> |
		<a href="/en/law/">Law</a> |
		<a href="/en/recipe/">Recipes</a> |
		<a href="/en/a/links.xhtml">Links</a> |
		<a href="/$filename.asc">{this page}.asc</a>
	</p>
	<hr/>

END;

		if($filename != 'en/coursework/index.xhtml' and substr($filename, 0, 14) == 'en/coursework/'):
			$xhtml['<{nav}>'] .= <<<'END'
	<p>
		<span class="hyperlink_unavailable" title="Art History">AHIST 1401</span> |
		<span class="hyperlink_unavailable" title="Biology 1 for Health Studies Majors">BIOL 1121</span> |
		<span class="hyperlink_unavailable" title="Introduction to Biology">BIOL 1301</span> |
		<a href="/en/coursework/BUS1101/" title="Principles of Business Management">BUS 1101</a> |
		<a href="/en/coursework/CS1101/" title="Programming Fundamentals">CS 1101</a> |
		<a href="/en/coursework/CS1102/" title="Programming 1">CS 1102</a> |
		<a href="/en/coursework/CS1103/" title="Programming 2">CS 1103</a> |
		<a href="/en/coursework/CS1104/" title="Computer Systems">CS 1104</a> |
		<a href="/en/coursework/CS2203/" title="Databases 1">CS 2203</a> |
		<a href="/en/coursework/CS2204/" title="Communications and Networking">CS 2204</a> |
		<a href="/en/coursework/CS2205/" title="Web Programming 1">CS 2205</a> |
		<a href="/en/coursework/CS2301/" title="Operating Systems 1">CS 2301</a> |
		<a href="/en/coursework/CS2401/" title="Software Engineering 1">CS 2401</a> |
		<a href="/en/coursework/CS3303/" title="Data Structures">CS 3303</a> |
		<a href="/en/coursework/CS3304/" title="Analysis of Algorithms">CS 3304</a> |
		<a href="/en/coursework/CS3305/" title="Web Programming 2">CS 3305</a> |
		<a href="/en/coursework/CS3306/" title="Databases 2">CS 3306</a> |
		<a href="/en/coursework/CS3307/" title="Operating Systems 2">CS 3307</a> |
		<a href="/en/coursework/CS3308/" title="Information Retrieval">CS 3308</a> |
		<a href="/en/coursework/CS4402/" title="Comparative Programming Languages">CS 4402</a> |
		<a href="/en/coursework/CS4403/" title="Software Engineering 2">CS 4403</a> |
		<a href="/en/coursework/CS4404/" title="Advanced Networking and Data Security">CS 4404</a> |
		<a href="/en/coursework/CS4405/" title="Mobile Applications">CS 4405</a> |
		<a href="/en/coursework/CS4406/" title="Computer Graphics">CS 4406</a> |
		<a href="/en/coursework/CS4407/" title="Data Mining and Machine Learning">CS 4407</a> |
		<a href="/en/coursework/CS4408/" title="Artificial Intelligence">CS 4408</a> |
		<span class="hyperlink_unavailable" title="Introduction to Economics">ECON 1580</span> |
		<a href="/en/coursework/ENGL1102/" title="English Composition 2">ENGL 1102</a> |
		<a href="/en/coursework/ENGL1405/" title="World Literature">ENGL 1405</a> |
		<a href="/en/coursework/ENVS1301/" title="Introduction to Environmental Sciences">ENVS 1301</a> |
		<a href="/en/coursework/HIST1421/" title="Greek and Roman Civilization">HIST 1421</a> |
		<a href="/en/coursework/MATH1201/" title="College Algebra">MATH 1201</a> |
		<a href="/en/coursework/MATH1211/" title="Calculus">MATH 1211</a> |
		<a href="/en/coursework/MATH1280/" title="Introduction to Statistics">MATH 1280</a> |
		<span class="hyperlink_unavailable" title="Statistical Inference">MATH 1281</span> |
		<a href="/en/coursework/MATH1302/" title="Discrete Mathematics">MATH 1302</a> |
		<a href="/en/coursework/PHIL1402/" title="Introduction to Philosophy">PHIL 1402</a> |
		<a href="/en/coursework/PHIL1404/" title="Ethics and Social Responsibility">PHIL 1404</a> |
		<a href="/en/coursework/POLS1503/" title="Globalization">POLS 1503</a> |
		<a href="/en/coursework/PSYC1111/" title="Introduction to Health Psychology (previously known as Introduction to Human Psychology)">PSYC 1111</a> |
		<a href="/en/coursework/PSYC1205/" title="Emotional intelligence (EI)">PSYC 1205</a> |
		<a href="/en/coursework/PSYC1504/" title="Introduction to Psychology">PSYC 1504</a> |
		<a href="/en/coursework/SOC1502/" title="Introduction to Sociology">SOC 1502</a> |
		<a href="/en/coursework/UNIV1001/" title="Online Education Strategies">UNIV 1001</a>
	</p>
	<hr/>

END;

// It's less work to maintain this if we have the script dynamically
// decide what the course code must be.
			$course_path_parts = explode('/', $filename);
// If there's an element number three, element two is the course code.
// Otherwise, we have no course code at all because we're not dealing
// with a course subdirectory.
			if(isset($course_path_parts[3])):
				$xhtml['<{nav}>'] .= "\t<p>\n\t\t{$coursework_nav[$course_path_parts[2]]}\n\t</p>\n\t<hr/>\n";
			endif;
		endif;

		if($filename != 'en/opinion/index.xhtml' and substr($filename, 0, 11) == 'en/opinion/'):
			$xhtml['<{nav}>'] .= <<<END
	<p>
		<a href="/en/opinion/XML.xhtml">$a[XML]</a> |
		<a href="/en/opinion/code_indentation.xhtml">Code indentation</a> |
		<a href="/en/opinion/free_culture.xhtml">Free culture</a> |
		<a href="/en/opinion/free_software.xhtml">Free software</a> |
		<a href="/en/opinion/holidays.xhtml">Holidays</a> |
		<a href="/en/opinion/misuse_of_words.xhtml">Misuse of words</a>
	</p>
	<hr/>

END;
		endif;
		if(substr($filename, 0, 10) == 'en/weblog/'):
			$current_entry = substr($xhtml['<{URI path minus slash}>'], 10);
			$current_entry = explode('/', $current_entry);
			$xhtml['<{nav}>'] .= <<<END
	<p>
		Weblog index:
		<a href="/en/weblog/memories">Memories</a> |
		<a href="/en/weblog/">$a[ASCII] calendars</a> |
		<a href="/en/weblog/index_ol_ascending.xhtml">Ascending list</a> |
		<a href="/en/weblog/index_ol_descending.xhtml">Descending list</a>
	</p>
	<hr/>

END;
			if(is_numeric($current_entry[0])):
				switch(count($current_entry)):
// Main weblog index:
					case 1:
					break;
// Weblog year index:
					case 2:
						$datetime = new DateTimeImmutable("$current_entry[0]-01-01");
						$previous = $datetime->sub($interval['year'])->format('Y');
						$next     = $datetime->add($interval['year'])->format('Y');
						$xhtml['<{nav}>'] .= <<<END
	<p>
		Jump to year:

END;
						if($filename != 'en/weblog/2015/index.xhtml'):
							$xhtml['<{nav}>'] .= <<<END
		<a href="/en/weblog/2015/">&lt;&lt;First</a>

END;
						endif;
						if(is_dir(__DIR__."/pages/en/weblog/$previous/")):
							$xhtml['<{nav}>'] .= <<<END
		<a rel="prev" href="/en/weblog/$previous/">&lt;Previous</a>

END;
						endif;
						if(is_dir(__DIR__."/pages/en/weblog/$next/")):
							$xhtml['<{nav}>'] .= <<<END
		<a rel="next" href="/en/weblog/$next/">Next&gt;</a>

END;
						endif;
						if("/$filename" != "$latest_entry[year]index.xhtml"):
							$xhtml['<{nav}>'] .= <<<END
		<a href="/en/weblog/latest_year.xhtml">Latest&gt;&gt;</a>

END;
						endif;
						$xhtml['<{nav}>'] .= <<<END
	</p>
	<hr/>

END;
					break;
					case 3:
// Weblog month index:
						if($current_entry[2] == ''):
							$current_entry[1] = explode('-', $current_entry[1])[0];
							$datetime = new DateTimeImmutable("$current_entry[0]-$current_entry[1]-01");
							$previous = $datetime->sub($interval['month'])->format('Y/m-F');
							$next     = $datetime->add($interval['month'])->format('Y/m-F');
							$xhtml['<{nav}>'] .= <<<'END'
	<p>
		Jump to month:

END;
							if($filename != 'en/weblog/2015/03-March/index.xhtml'):
								$xhtml['<{nav}>'] .= <<<'END'
		<a href="/en/weblog/2015/03-March/">&lt;&lt;First</a>

END;
							endif;
							if(is_dir(__DIR__."/pages/en/weblog/$previous/")):
								$xhtml['<{nav}>'] .= <<<END
		<a rel="prev" href="/en/weblog/$previous/">&lt;Previous</a>

END;
							endif;
							if(is_dir(__DIR__."/pages/en/weblog/$next/")):
								$xhtml['<{nav}>'] .= <<<END
		<a rel="next" href="/en/weblog/$next/">Next&gt;</a>

END;
							endif;
							if("/$filename" != "$latest_entry[month]index.xhtml"):
								$xhtml['<{nav}>'] .= <<<'END'
		<a href="/en/weblog/latest_month.xhtml">Latest&gt;&gt;</a>

END;
							endif;
							$xhtml['<{nav}>'] .= <<<'END'
	</p>
	<hr/>
END;
// Weblog day entry:
						else:
							$current_entry[1] = explode('-', $current_entry[1])[0];
							$current_entry[2] = explode('.', $current_entry[2])[0];
							$datetime = new DateTimeImmutable("$current_entry[0]-$current_entry[1]-$current_entry[2]");
							$previous = $datetime->sub($interval['day'])->format('Y/m-F/d');
							$next     = $datetime->add($interval['day'])->format('Y/m-F/d');
							$xhtml['<{subtitle}>'] = $entry($current_entry[0], $current_entry[1], $current_entry[2]);
							$xhtml['<{nav}>'] .= <<<'END'
	<p>
		Jump to entry:

END;
							if($filename != 'en/weblog/2015/03-March/07.xhtml'):
								$xhtml['<{nav}>'] .= <<<'END'
		<a href="/en/weblog/2015/03-March/07.xhtml">&lt;&lt;First</a>

END;
							endif;
							if(file_exists(__DIR__."/pages/en/weblog/$previous.xhtml")):
								$xhtml['<{nav}>'] .= <<<END
		<a rel="prev" href="/en/weblog/$previous.xhtml">&lt;Previous</a>

END;
							endif;
							if(file_exists(__DIR__."/pages/en/weblog/$next.xhtml")):
								$xhtml['<{nav}>'] .= <<<END
		<a rel="next" href="/en/weblog/$next.xhtml">Next&gt;</a>

END;
							endif;
							if("/$filename" != $latest_entry['day']):
								$xhtml['<{nav}>'] .= <<<'END'
		<a href="/en/weblog/latest.xhtml">Latest&gt;&gt;</a>

END;
							endif;
							$xhtml['<{nav}>'] .= <<<'END'
			</p>
			<hr/>

END;
						endif;
					break;
					default:
						throw new \st\y\exception\unexpected_value("The weblog section of the source directory tree has an anomaly. File path \"$filename\" detected.", '[000000]');
				endswitch;

// Automatic copyright dating of journal entries:
				if(empty($xhtml['<{copyright year}>']) and !empty($current_entry[0])):
					$xhtml['<{copyright year}>'] = $current_entry[0];
				endif;
			endif;
		endif;
	endif;

	$xhtml['<{nav}>'] .= '</nav>';

	if(!isset(
		$xhtml['<{copyright year}>'],
		$xhtml['<{URI path minus slash}>'],
		$xhtml['<{encoded path minus slash}>'],
		$xhtml['<{title}>'],
		$xhtml['<{subtitle}>'],
		$xhtml['<{stripped title}>'],
		$xhtml['<{nav}>'],
		$xhtml['<{body}>']
	) or count($xhtml) != 8):
		var_dump(array_keys($xhtml));
		throw new \st\y\exception\unexpected_value("File '$filename' has invalid data.", '[000000]');
	endif;

return $xhtml; };

$¢_build_page = function(string $filename, array $xhtml) {
	global $pgp;
	global $should_exist;
	global $¢_set_data_from_path;
	global $template;

	$xhtml = $¢_set_data_from_path($filename, $xhtml);
	$page = strtr($template, $xhtml);
/*
// Automated page validation
	$validate = new DOMDocument;
	$validate->load(__DIR__."/../compiled/$filename");
	var_dump($filename);
	if(!$validate->validate()):
// Due to an error in PHP's DOM module, it throws errors when a
// document is invalid instead of simply returning false. Our error
// handler deliberately makes all errors fatal, so this exception will
// never be thrown. However, we have it here anyway in case the error
// in PHP's DOM module is ever corrected.
		throw new Exception("File '$filename' seems to produce invalid XML.");
	endif;
*/
	$should_exist[$filename] = true;
	$should_exist["$filename.asc"] = true;
	$dirname = dirname(__DIR__."/../compiled/$filename");
	if(!is_dir($dirname)):
		mkdir($dirname, 0777, true);
	endif;
	if(\st\y\xml_is_clean($page)):
		\st\y\update_file(__DIR__."/../compiled/$filename", $page, $pgp);
	else:
		throw new \st\y\exception\unexpected_value("UNCLEAN PAGE MARKUP: $filename", '[000000]');
	endif;
};
